home *** CD-ROM | disk | FTP | other *** search
- ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
- ' Asteroid demo
-
- ' Screen mode
- TextMode (TEXT_BUFFERED) ' Don't draw sprites until explicitly told to do so
- ResizeSpriteArea (800, 600)
-
- ' Player state
- struc SPlayer
- dim sprite
- dim index
- dim lives, score, deadCounter, invincibleCounter, ingame
- dim leftKey, rightKey, thrustKey, shootKey
- dim wasShooting
- dim col#(3)
- endstruc
-
- ' Bullets
- struc SBullet
- dim sprite, life, SPlayer &player
- endstruc
-
- ' Asteroids
- struc SAsteroid
- dim sprite, dir#
- endstruc
-
- ' Initialise gamestate
- const maxPlayers = 2
- const maxBullets = 200
- const maxAsteroids = 200
- const maxExplosions = 200
- dim SPlayer players(maxPlayers), SPlayer &player
- dim SBullet bullets(maxBullets), SBullet &bullet, bulletCount
- dim SAsteroid asteroids(maxAsteroids), SAsteroid &asteroid, SAsteroid &newAsteroid, asteroidCount
- dim explosions(maxExplosions), explosionCount
- dim levelCounter, counter
- dim level, dead
- dim i, j, k, temp#, vec#(1), centreVec#(1), size#, maxSize#, count
-
- ' Sprite textures
- dim shipTex, rockTex, ballTex
- shipTex = LoadTexture ("data\F117.png")
- rockTex = LoadTexture ("data\asteroid.png")
- ballTex = LoadTexture ("data\ball.png")
-
- ' Animations
- dim explodeTex (ImageStripFrames ("data\explode.png") - 1)
- explodeTex = LoadMipmapImageStrip ("data\explode.png")
-
- ' Tile textures
- dim tileTex (ImageStripFrames ("data\spacetiles.png") - 1)
- tileTex = LoadMipmapImageStrip ("data\spaceTiles.png")
-
- ' Setup tile map
- dim tileMap, t(9)(9)
- tileMap = NewTileMap (tileTex)
- data 2,2,3,1,2,1,1,3,2,3
- data 3,3,2,3,2,3,2,3,2,2
- data 3,1,2,3,3,4,3,2,3,3
- data 2,1,4,2,5,3,3,1,2,1
- data 2,3,2,3,3,1,2,3,3,3
- data 2,2,2,1,2,2,3,1,3,2
- data 3,1,3,1,2,2,2,2,1,3
- data 2,1,2,4,1,3,2,3,2,3
- data 2,2,3,2,3,3,2,3,3,1
- data 3,2,1,2,3,2,1,2,2,1
- for i = 0 to 9
- for j = 0 to 9
- read t(i)(j)
- next
- next
- SprSetTiles (t)
- SprSetZOrder (100) ' Push tile map to back
- SprSetScale (2)
-
- ' Sound effects
- dim shootSound, explodeSound
- shootSound = LoadSound ("sounds\laser.wav")
- explodeSound = LoadSound ("sounds\gunshot5.wav")
-
- ' Setup keys
- players(1).index = 1
- players(1).leftKey = VK_LEFT
- players(1).rightKey = VK_RIGHT
- players(1).thrustKey = VK_UP
- players(1).shootKey = VK_SPACE
- players(1).col# = vec4(.7,.7,.6,1)
- players(2).index = 2
- players(2).leftKey = Asc("A")
- players(2).rightKey = Asc("D")
- players(2).thrustKey = Asc("W")
- players(2).shootKey = Asc("F")
- players(2).col# = vec4(.3,.6,.8,1)
-
- goto start
-
- return
-
- ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
- ' Routines
- NewPlayer:
-
- ' Create player sprite
- player.sprite = NewSprite (shipTex)
- SprSetSize (32, 32)
- SprSetColor (player.col#)
-
- ' Initialise player settings
- player.ingame = true
- player.lives = 3
- player.score = 0
-
- ' Spawn player at centre
- gosub Spawn
- return
-
- Spawn:
-
- ' Set player alive again
- player.deadCounter = 0
- BindSprite (player.sprite)
- SprSetVisible (true) ' Show sprite
-
- ' Place player at centre of screen
- gosub CentrePlayer
- return
-
- CentrePlayer:
- player.invincibleCounter = 300
- BindSprite (player.sprite)
- SprSetPos (SpriteAreaWidth () / 2, SpriteAreaHeight () / 2)
- SprSetAngle (0)
- SprSetVel (0, 0)
- return
-
- Clamp:
- ' Clamp sprite s to screen range
- if SprX () < -32 then
- SprSetX (SprX () + SpriteAreaWidth () + 64)
- endif
- if SprX () >= SpriteAreaWidth () + 32 then
- SprSetX (SprX () - (SpriteAreaWidth () + 64))
- endif
- if SprY () < -32 then
- SprSetY (SprY () + SpriteAreaHeight () + 64)
- endif
- if SprY () >= SpriteAreaHeight () + 32 then
- SprSetY (SprY () - (SpriteAreaHeight () + 64))
- endif
- return
-
- MakeExplosion:
-
- ' Make explosion at vec#
- if explosionCount < maxExplosions then
- explosionCount = explosionCount + 1
- explosions (explosionCount) = NewSprite (explodeTex)
- SprSetSize (64, 64)
- SprSetPos (vec#)
- SprSetAnimSpeed (.4 / size#)
- SprSetAnimLoop (false)
- SprSetScale (size#)
- endif
- return
-
- MakeExplosions:
-
- ' Make explosions
- for k = 1 to count
- vec# = centreVec# + vec2 (Rnd () % 21 - 10, Rnd () % 21 - 10)
- size# = maxSize# * (Rnd () % 6 + 5) / 10.0
- gosub MakeExplosion
- next
- return
-
- MakeSmoke:
- if explosionCount < maxExplosions then
- explosionCount = explosionCount + 1
- explosions (explosionCount) = NewSprite (explodeTex)
- SprSetSize (64, 64)
- SprSetPos (vec#)
- SprSetFrame (10)
- SprSetAnimSpeed (.1)
- SprSetAnimLoop (false)
- SprSetScale (.4)
- endif
- return
-
- ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
- ' Mainloop
- start:
-
- NextLevel:
-
- level = level + 1
- levelCounter = 200
-
- ' Create asteroids
- asteroidCount = level * 2 + 1
- for i = 1 to asteroidCount
- &asteroid = &asteroids (i)
- asteroid.sprite = NewSprite (rockTex)
- SprSetSize (24, 24)
- SprSetScale (4)
- SprSetZOrder (SprScale ())
- SprSetPos (rnd () % int (SpriteAreaWidth ()), rnd () % int (SpriteAreaHeight ()))
- SprSetSpin (.25)
- asteroid.dir# = rnd () % 360
- SprSetVel (MatrixRotateZ (asteroid.dir#) * vec2 (0, 2) / SprScale ())
- next
-
- ' Delete player bullets
- for i = 1 to bulletCount
- DeleteSprite (bullets (i).sprite)
- next
- bulletCount = 0
-
- ' Delete explosions
- for i = 1 to explosionCount
- DeleteSprite (explosions (i))
- next
- explosionCount = 0
-
- ' Recentre players
- for i = 1 to maxPlayers
- &player = &players (i)
- if player.inGame and player.deadCounter = 0 then
- gosub CentrePlayer
- endif
- next
-
- locate 16, 12: print "Level " + level
- DrawText ()
- Sleep (1000)
-
- while asteroidCount > 0 or levelCounter > 0
- if asteroidCount = 0 then
- levelCounter = levelCounter - 1
- endif
-
- ' Update gameplay
- Joy_Keys ()
- while SyncTimer (10)
- counter = counter + 1
- AnimateSprites ()
-
- ' Move players
- for i = 1 to MaxPlayers
- &player = &players (i)
-
- ' Counters
- if player.inGame then
- if player.deadCounter > 0 then
- player.deadCounter = player.deadCounter - 1
- if player.deadCounter = 0 then
- if player.lives > 0 then
- player.lives = player.lives - 1
- gosub Spawn
- else
- player.ingame = false
- endif
- endif
- endif
- if player.invincibleCounter > 0 then
- player.invincibleCounter = player.invincibleCounter - 1
- BindSprite (player.sprite)
- SprSetVisible ((player.invincibleCounter and 16) = 0)
- endif
- endif
-
- ' Shooting/spawning
- if ScanKeyDown (player.shootKey) then
- if not player.wasShooting then
- if not player.inGame then
-
- ' Put player in game
- gosub NewPlayer
- else
- if player.deadCounter = 0 and player.invincibleCounter = 0 and bulletCount < maxBullets then
-
- ' Shoot bullet
- bulletCount = bulletCount + 1
- &bullet = &bullets (bulletCount)
- bullet.sprite = NewSprite (ballTex)
- SprSetZOrder (10)
- SprSetSize (16, 16)
- SprSetPos (SprPos (player.sprite))
- SprSetVel (SprVel (player.sprite) + MatrixRotateZ (SprAngle (player.sprite)) * vec2 (0, -3.5))
- bullet.life = 100
- &bullet.player = &player
- PlaySound (shootSound)
- endif
- endif
- endif
- player.wasShooting = true
- else
- player.wasShooting = false
- endif
-
- if player.inGame and player.deadCounter = 0 then
-
- ' Moving
- BindSprite (player.sprite)
- if ScanKeyDown (player.leftKey) then
- SprSetAngle (SprAngle () - 3)
- endif
- if ScanKeyDown (player.rightKey) then
- SprSetAngle (SprAngle (player.sprite) + 3)
- endif
- if ScanKeyDown (player.thrustKey) then
- SprSetVel (SprVel () + MatrixRotateZ (SprAngle ()) * vec2 (0, -.035))
- vec# = SprPos () + MatrixRotateZ (SprAngle ()) * vec2 (0, 15)
- if (counter and 7) = 0 then
- gosub MakeSmoke
- endif
- endif
- gosub Clamp
-
- ' Check for collisions with asteroids
- if player.invincibleCounter = 0 then
- for j = 1 to asteroidCount
- &asteroid = &asteroids (j)
- BindSprite (asteroid.sprite)
- if Length (SprPos () - SprPos (player.sprite)) < SprScale () * SprXSize () / 2 + 4 then
-
- ' Make explosions
- centrevec# = SprPos (player.sprite)
- count = 5
- maxSize# = 2
- gosub MakeExplosions
-
- ' Explosion sound
- PlaySound (explodeSound)
-
- ' Hide player sprite
- BindSprite (player.sprite)
- SprSetVisible (false)
-
- ' Mark player as dead
- player.deadCounter = 300
- endif
- next
- endif
- endif
- next
-
- ' Move bullets
- i = 1
- while i <= bulletCount
- &bullet = &bullets(i)
-
- ' Clamp bullet pos
- BindSprite (bullet.sprite)
- gosub Clamp
-
- ' Bullet has only limited life
- bullet.life = bullet.life - 1
- dead = bullet.life <= 0
-
- ' Test for collisions with asteroids
- j = 1
- while j <= asteroidCount
- &asteroid = &asteroids (j)
- BindSprite (asteroid.sprite)
- if Length (SprPos () - SprPos (bullet.sprite)) < SprScale () * SprXSize () / 2 then
-
- ' Make explosion
- centrevec# = SprPos ()
- count = SprScale () * 2
- maxSize# = (SprScale () + 1) * 0.3
- gosub MakeExplosions
-
- ' Need to rebind after explosion routine
- BindSprite (asteroid.sprite)
-
- ' Destroy small asteroids
- if SprScale () <= 1 then
- DeleteSprite (asteroid.sprite)
- asteroid = asteroids (asteroidCount)
- asteroidCount = asteroidCount - 1
- if asteroidCount = 0 then
- bullet.player.score = bullet.player.score + 200
- endif
- bullet.player.score = bullet.player.score + 20
- else
- ' Otherwise split them
- ' Shrink existing one
- SprSetScale (SprScale () / 2)
- SprSetZOrder (SprScale ())
- SprSetSpin (SprSpin () * 4)
-
- ' Create new duplicate asteroid
- asteroidCount = asteroidCount + 1
- &newAsteroid = &asteroids (asteroidCount)
- newAsteroid = asteroid
- newAsteroid.sprite = NewSprite ()
- CopySprite (asteroid.sprite)
-
- ' Add some random directional deviation
- temp# = rnd () % 35 + 10
- asteroid.dir# = asteroid.dir# + temp#
- newAsteroid.dir# = newAsteroid.dir# - temp#
-
- ' Recalculate velocities
- BindSprite (asteroid.sprite)
- SprSetVel (MatrixRotateZ (asteroid.dir#) * vec2 (0, 2) / SprScale ())
- BindSprite (newAsteroid.sprite)
- SprSetVel (MatrixRotateZ (newasteroid.dir#) * vec2 (0, 2) / SprScale ())
- bullet.player.score = bullet.player.score + 10
- endif
- PlaySound (explodeSound)
- j = asteroidCount + 1
- dead = true
- else
- j = j + 1
- endif
- wend
-
- if dead then
-
- ' Delete bullet
- vec# = SprPos (bullet.sprite)
- gosub MakeSmoke
- DeleteSprite (bullet.sprite)
- bullet = bullets (bulletCount)
- bulletCount = bulletCount - 1
- else
- i = i + 1
- endif
- wend
-
- ' Move asteroids
- for i = 1 to asteroidCount
- BindSprite (asteroids (i).sprite)
- gosub Clamp
- next
-
- ' Remove completed explosion animations
- i = 1
- while i <= explosionCount
- if SprAnimDone (explosions (i)) then
- DeleteSprite (explosions (i))
- explosions (i) = explosions (explosionCount)
- explosionCount = explosionCount - 1
- else
- i = i + 1
- endif
- wend
-
- ' Animate tile map
- BindSprite (tileMap)
- SprSetPos (SprPos () + vec2 (.1, .2))
- wend
-
- ' Update display
- cls
- if players (1).inGame then
- locate 0, 0: print "Score=" + players (1).score
- locate 0, 1: print "Lives=" + players (1).lives
- endif
- if players (2).inGame then
- locate 30, 0: print "Score=" + players (2).score
- locate 30, 1: print "Lives=" + players (2).lives
- endif
- if not (players (1).inGame or players (2).inGame) then
- locate 10, 12: print "Press Space to Start"
- endif
-
- ' Draw sprites
- DrawText ()
- wend
-
- goto NextLevel
-